﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using BackgroundAudioPlayback;
using Microsoft.Phone.BackgroundAudio;
using Microsoft.Phone.Shell;
using SQLite;
using WOIM_NET.Annotations;

namespace WOIM_NET.Music
{
    public class AlbumModel : INotifyPropertyChanged
    {
        private string _avatar;
        private string _name;
        private string _url;
        private string _artist;
        private string _numberofSongs;
        private string _details;
        private string _typeOfInstrumental;
        public ObservableCollection<SongModel> ListSongs { get; private set; }

        public AlbumModel()
        {
            this.ListSongs = new ObservableCollection<SongModel>();
        }

        public bool IsDataLoaded { get; private set; }

        public void GetSongTracks()
        {
            ListSongs.Clear();
            ListSongs.Add(new SongModel(){ Name = "Loading...."});
            HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(new Uri(_url));
            webRequest.BeginGetResponse(httpRequestCallback, webRequest);
        }
        private void httpRequestCallback(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            try
            {
                WebResponse response = request.EndGetResponse(result);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    string htmlCode = reader.ReadToEnd();
                    //Get Album info
                    Regex info = new Regex(@"<div\sclass=.rotate_album.><img\ssrc=.(?<image>http://p.img.nct.nixcdn.com/playlist/[^""]+)""\salt=""(?<albumname>[^""]+)");
                    Match matchInfo = info.Match(htmlCode);
                    if (matchInfo.Success)
                    {
                        this.Avatar = matchInfo.Groups["image"].ToString();
                        this.Name = matchInfo.Groups["albumname"].ToString();
                    }
                    Regex regex =
                        new Regex(
                            @"http://www.nhaccuatui.com/flash/xml?[^""]+");
                    MatchCollection matchs = regex.Matches(htmlCode);
                    //GetAudioTracks(); //Woim Region
                    //Get songs from album NCT
                    HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(new Uri(matchs[0].ToString()));
                    webRequest.BeginGetResponse(getSongsCallback, webRequest);

                });
            }
            catch (WebException ex)
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show("Error on get tracks name!"));
            } 
        }

        private void getSongsCallback(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            try
            {
                WebResponse response = request.EndGetResponse(result);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    string htmlCode = reader.ReadToEnd();
                    //Filter Data
                    Regex regex = new Regex(@"<title>\s+<!\[CDATA\[(?<title>[^\]]+)\]\]>\s+</title>\s+<creator>\s+<!\[CDATA\[(?<artist>[^\]]+)\]\]>\s+</creator>\s+<location>\s+<!\[CDATA\[(?<linkmp3>http://[A-Za-z0-9-/_\.]+)\]\]>\s+</location>");
                    MatchCollection matchs = regex.Matches(htmlCode);
                    this.ListSongs.Clear();
                    foreach (Match match in matchs)
                    {
                        this.ListSongs.Add(new SongModel() { Name = match.Groups["title"].ToString(), Url = match.Groups["linkmp3"].ToString(), Artist = match.Groups["artist"].ToString()});
                    }
                    AddTracksToDatabase();
                    IsDataLoaded = true;
                });
            }
            catch (WebException ex)
            {

            } 
        }

        private void AddTracksToDatabase()
        {
            using (var db = new SQLiteConnection(App.dbPath))
            {
                db.RunInTransaction(() =>
                {
                    db.DeleteAll<PlayingList>();

                    foreach (SongModel song in ListSongs)
                    {
                        db.Insert(new PlayingList() { Title = song.Name, Url = song.Url, Artist = song.Artist, Album = this.Name, Avatar = this.Avatar, LinkToAlbum = this.Url});
                    }
                });
            }
            BackgroundAudioPlayer.Instance.Play(); 
        }

        #region Woim.net

        private void GetAudioTracks()
        {
            foreach (SongModel song in ListSongs)
            {
                HttpWebRequest webRequest = (HttpWebRequest) HttpWebRequest.Create(new Uri(song.Url));
                webRequest.BeginGetResponse(getTrackInfo, webRequest);
            }
        }

        private void getTrackInfo(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest) result.AsyncState;
            try
            {
                WebResponse response = request.EndGetResponse(result);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    string htmlCode = reader.ReadToEnd();
                    Regex regex =
                        new Regex(
                            @"code=(?<link>http://www.woim.net/list/\d+/\d+/[a-z0-9]+)");
                    Match match = regex.Match(htmlCode);
                    if (match.Success)
                    {
                        HttpWebRequest webRequest =
                            (HttpWebRequest) HttpWebRequest.Create(new Uri(match.Groups["link"].ToString()));
                        webRequest.BeginGetResponse(getLinkMp3, webRequest);
                    }
                });
            }
            catch (WebException ex)
            {
                //System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show("Error on get link xml!"));
            }
        }

        private void getLinkMp3(IAsyncResult result)
        {
            HttpWebRequest req = (HttpWebRequest) result.AsyncState;
            try
            {
                WebResponse response = req.EndGetResponse(result);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    string htmlCode = reader.ReadToEnd();
                    Regex regex =
                        new Regex(
                            @"location=.(?<linkmp3>http://data.woim.net/hoaihung/[A-Za-z0-9-_]+/[A-Za-z0-9-_]+/[0-9a-zA-Z\.-_]+.></track>(?<songName>[A-Za-z0-9-_,!&\*()\.;@\s]+)");
                    Match match = regex.Match(htmlCode);
                    if (match.Success)
                    {

                    }
                    //SetProgressIndicator(false);
                });
            }
            catch (WebException ex)
            {
                //System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show("Error on get link mp3!"));
            }
        }

        #endregion


        public string TypeOfInstrumental
        {
            get { return _typeOfInstrumental; }
            set
            {
                if (value == _typeOfInstrumental) return;
                _typeOfInstrumental = value;
                OnPropertyChanged("TypeOfInstrumental");
            }
        }

        public string Details
        {
            get { return _details; }
            set
            {
                if (value == _details) return;
                _details = value;
                OnPropertyChanged("Details");
            }
        }

        public string Avatar
        {
            get { return _avatar; }
            set
            {
                if (value == _avatar) return;
                _avatar = value;
                OnPropertyChanged("Avatar");
            }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (value == _name) return;
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        public string Url
        {
            get { return _url; }
            set
            {
                if (value == _url) return;
                _url = value;
                OnPropertyChanged("Url");
            }
        }

        public string Artist
        {
            get { return _artist; }
            set
            {
                if (value == _artist) return;
                _artist = value;
                OnPropertyChanged("Artist");
            }
        }

        public string NumberofSongs
        {
            get { return _numberofSongs; }
            set
            {
                if (value == _numberofSongs) return;
                _numberofSongs = value;
                OnPropertyChanged("NumberofSongs");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
